package com.lx.spring.anno.junit;

import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.util.ArrayList;
import java.util.List;

public class junitRunner {

    public static void main(String[] args) throws InvocationTargetException, InstantiationException, IllegalAccessException {
        junitRunner jr = new junitRunner();
        jr.runTest(MathBizTest.class);
    }

    public void runTest(Class testClass) throws InstantiationException, IllegalAccessException, InvocationTargetException {
        // 创建测试对象
        // 相当于 new XXX()
        Object tester = testClass.newInstance();

        List<Method> befores = new ArrayList<>();
        List<Method> afters = new ArrayList<>();
        List<Method> tests = new ArrayList<>();

        Method[] methods = testClass.getDeclaredMethods();

        for (Method method : methods) {
            if(method.getAnnotation(Before.class) != null){
                befores.add(method);
            }
            if(method.getAnnotation(After.class) != null){
                afters.add(method);
            }
            if(method.getAnnotation(Test.class) != null){
                tests.add(method);
            }
        }

        List<Method> sortTest = new ArrayList<>();

        for(int i = 0; i < tests.size(); i++){
            sortTest.add(null);
        }

        // TODO 对测试方法排序
        int True = 0;
        int False = 0;
        int Ex = 0;
        for(int i = 0; i < tests.size(); i++){
            sortTest.set((int)tests.get(i).getAnnotation(Test.class).value() - 1, tests.get(i));
        }
        System.out.println(sortTest);
        for (Method method : sortTest) {
            for(Method beforeMethod : befores){
                beforeMethod.invoke(tester);
            }
            try {
                method.invoke(tester);
            } catch (AssertException e) {
                System.out.println("测试结果错误");
                False++;
            } catch (InvocationTargetException e) {
                //获取异常原因
                Throwable cause = e.getCause();
                System.out.println("方法业务异常" + cause);
                Ex++;
            }
            //测试方法执行到这表示测试通过
            for(Method after : afters){
                after.invoke(tester);
            }
        }
        True = sortTest.toArray().length - False - Ex;
        //TODO 统计正确的测试结果数量，异常和错误数量
        System.out.println("测试错误数:" + False);
        System.out.println("方法业务异常数:" + Ex);
        System.out.println("正确的测试结果数量:" + True);
        System.out.println("测试结束");
    }
}
@Retention(RetentionPolicy.RUNTIME)
@interface Test{
    int value();
}
@Retention(RetentionPolicy.RUNTIME)
@interface Before{

}
@Retention(RetentionPolicy.RUNTIME)
@interface After{

}

class Assert{
    public static void assertEquals(Object aspect, Object act){
        if(!aspect.equals(act)){
            String s = String.format("期待结果是:%s, 实际结果是:%s", aspect, act);
            throw new AssertException(s);
        }
    }
}

class AssertException extends RuntimeException{
    public AssertException(String s){
        super(s);
    }
}
